﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Creates a sepia matrix by creating a color matrix and applies it to the given picture.
    /// </summary>
    public class Sepia : BaseImageFilter
    {
        /// <summary>
        /// Default Constructor
        /// </summary>
        public Sepia()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Sepia"/> class.
        /// </summary>
        /// <param name="_sepia">The _sepia.</param>
        internal Sepia(Sepia _sepia)
        {
        }

        /// <summary>
        /// Create SepiaMatrix
        /// </summary>
        /// <returns></returns>
        protected static ColorMatrix CreateSepiaMatrix()
        {
            return new ColorMatrix(new float[][]{
                new float[] {0.393f, 0.349f, 0.272f, 0, 0},
                new float[] {0.769f, 0.686f, 0.534f, 0, 0},
                new float[] {0.189f, 0.168f, 0.131f, 0, 0},
                new float[] {     0,      0,      0, 1, 0},
                new float[] {     0,      0,      0, 0, 1}
            });
        }

        /// <summary>
        /// Apply sepia matrix to image
        /// </summary>
        /// <param name="_bitmap"></param>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            _bitmap.Dispose();
            Image img = (Image)_bitmap.InternalBitmap;
            ImageAttributes imageAttributes = new ImageAttributes();
            imageAttributes.SetColorMatrix(CreateSepiaMatrix());
            using (Graphics g = System.Drawing.Graphics.FromImage(img))
            {
                g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height),
                    0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imageAttributes);
            }
            return _bitmap;
        }

        /// <summary>
        /// use this to create a deep copy
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new Sepia(this);
        }
    }
}
